let router = require('../router/Router');

let config = require('../config/config');
let P = require("bluebird");

let Token = require('../token');
let http = require('http');
let cnst = require('../const');
let fileUtil = require('../util/fileUtil');
let ipUtil = require('../util/ipUtil');
let wxsign = require('../util/wxsign');
let wxUtil = require('../util/wxUtil');
let userService = require('../service/userService');
let redis=require('../dao/redis');
let wxService = require('../service/wxService')
let redisConst = require('../const/redisConst')
let tokenService = require('../service/TokenService')
let cacheService = require('../service/RoomCacheService')
//let Token = require('../token');
//let redis=new predis({port:6379,host:'101.37.164.134'});

const { BusiError, SysError } = require('../exception/exception');

router.get('/weixin/getimg', function (req, res) {
    //let imgurl = new Buffer(req.query.imgurl,'base64').toString();
    //http://weixin.g9527.com:3013/active/getimg?imgurl=http%3A%2F%2Fwx.qlogo.cn%2Fmmopen%2Fk0Ue4mIpaVicAXoZ3uiadCxaeJia2P1n1Puqz8cSmrYRjGzYplFpWyBaph981jQWUu2tD7hZwH29jDclN7sjAC3GQ%2F0&type=a.jpg
    let imgurl = decodeURIComponent(req.query.imgurl);
    console.logw('get img', imgurl);
    http.get(imgurl, function (res0) {
        let type = res0.headers['content-type'];
        res.setHeader('content-type', type);
        res0.pipe(res);
    }).on('error', function (err) {
        console.logw('http getImage error', err);
        res.header("Cache-Control", "public, max-age=0");
        res.send({ code: 501, msg: 'get remote img error' });
    }).on('end', function (err) {
        console.logw('redirect img end');
        res.end();
    }).setTimeout(5000, function () {
        console.logw('get img timeout');
        res.end();
    });
});

function httpRequest(url, cb) {
    http.get(url, function (req, res) {
        let html = '';
        req.on('data', function (data) {
            html += data;
        });
        req.on('end', function () {

            cb(0, html);
        });
        req.on('error', function () {
            cb(0, '');
        });
    });
}

router.httpGet = P.coroutine(function* (url) {
    let getAsync = P.promisify(httpRequest);
    let res = yield getAsync(url);
    return res;
});

router.get('/weixin/guestLogin', function (req, resp) {
    let query = req.query;
    let uid = req.query.uid;
    let token = req.query.token;
    let ip = ipUtil.getIp(req, resp);
    let gameType = req.query.gameType;
    userService.loginByTokenOrUUID(token, uid, req.ip, req.ua, "").then(res => {
        res.code = 200;
        res.msg = "success";
        resp.send(res);
    }).catch(e => {
        let msg = "系统异常, 请稍后再试";
        if (e instanceof BusiError) {
            msg = e.message;
        }

        resp.send({ code: 500, msg: msg });
    });
});

router.get('/weixin/checkSign', function (req, res) {
    let token = req.query.token;
    let wxCode = req.query.wxCode;
    let rawUrl = req.query.url;
    let url = decodeURIComponent(req.query.url);
    console.log('checkSign url=', url);
    let uid = -1;
    let os = '';
    try {
        uid = Token.aesDecodeDef(token);
        if (uid == null) uid = -1;
    } catch (e) {
        console.logw('decode token failed ', token, 'uid', uid);
        res.send({ code: 500, msg: 'invalid uid' });
        return;
    }
    let doAsync = P.coroutine(function* () {
        console.logw("user uid", uid);
        if (config.myip !== config.accessHost) {
            if (router.accessUrlCount === undefined) router.accessUrlCount = 0;
            let len = config.accessUrls.length;
            let index = router.accessUrlCount % len;
            let aurl = config.accessUrls[index];
            let url = aurl + '/weixin/checkSign?wxCode=' + wxCode + '&token=' + token + '&url=' + decodeURIComponent(rawUrl);
            console.logw('checkSign from remote host ' + url);
            let ret = yield router.httpGet(url);
            console.logw('ret ', ret);
            res.send(ret);
            return;
        }

        let url = decodeURIComponent(req.query.url);
        let jsTicket = yield router.getJsapi_ticketCache(uid);
        if (jsTicket) {

            console.logw("return for getJsapi_ticketCache", jsTicket, url);
            let ret = wxsign(jsTicket.ticket, url);
            ret.appId = cnst.wx_appid;
            res.send({ code: 200, data: ret });
            return;
        }
        let info = yield router.getApiAccessToken(wxCode, 'normal');
        if (!info) {
            console.logw('获取api access token 失败');
            res.send({ code: 500, msg: '获取api access token 失败' });
            return;
        }
        jsTicket = yield router.getJsapi_ticketWeb(info.access_token, uid);
        if (jsTicket == null) {
            console.logw('重新获取accessToken');
            info = yield router.getApiAccessToken(wxCode, 'normal');
            jsTicket = yield router.getJsapi_ticketWeb(info.access_token, uid);
        }
        let ret = wxsign(jsTicket.ticket, url);
        ret.appId = cnst.wx_appid;
        res.send({ code: 200, data: ret });
    });
    doAsync().catch(function (e) {
        res.send({ code: 500, msg: 'excepsion ' + e.message });
    });
});

router.get('/weixin/login',function(req,res){
    let code = req.query.code;
    let xxCode=req.query.xxCode;
    let  token=req.query.token;
    let  ip= ipUtil.getIp(req,res);
    let stoken=Token.aesEncodeDef(ip);
    let os='';
    //let uid=-1;
    let doAsync= P.coroutine(function*() {
        let  needAuth=true;
        let  offlineData='';
        let  version=yield redis.getString("version");
        if(!version)  version='default';
        console.log("xxCode ",xxCode)

        if(xxCode)
        {
            var   userUid=yield userService.getUidByXxCode(xxCode)
            console.logw("xxCode ",xxCode,userUid)
            if(userUid)
            {
                console.logw("从xxCode中获得用户uid 进行登录")
                var  userInfo=yield  userService.getUserInfoByUid(userUid);
                if(userInfo)
                {
                    var  ret=userInfo;
                    ret.password="";
                    ret.token=yield tokenService.updateToken(ret.uid);
                    ret.stoken=stoken;
                    ret.phoneNoCheck=1;
                    ret.version=version;
                    ret.code=200;
                    if(ret.phoneCode === ret.codeNocheck && ret.phoneCode)  ret.phoneNoCheck=0;
                    console.logw('login by  xxCode ',JSON.stringify(ret));
                    res.send(ret);
                    return;
                }

            }
        }

        if(token&&!code)
        {
            try {
                let validRes = yield tokenService.validToken(token);
                var uid = validRes;
            } catch (e) {
                console.logw("token valid failed:", e.message, e);
                uid=null;
                //throw new BusiError(500, "无效token");
            }
            if(uid>100)
            {
                console.logw("从token中获得用户uid 进行登录 ",uid)
                var  userInfo=yield  userService.getUserInfoByUid(uid);
                if(userInfo)
                {
                    var  ret=userInfo;
                    ret.password="";
                    ret.token=yield tokenService.updateToken(ret.uid);
                    ret.stoken=stoken;
                    ret.phoneNoCheck=1;
                    ret.version=version;
                    ret.code=200;
                    if(ret.phoneCode === ret.codeNocheck && ret.phoneCode)  ret.phoneNoCheck=0;
                    console.logw('login by  token ',JSON.stringify(ret));
                    res.send(ret);
                    return;
                }
            }
            
        }


        let  accessInfo=yield wxService.getWxCodeCache(code);
        //判断缓存中是否存在微信信息，如果不存在则调用授权接口获取
        if(!accessInfo) {
            //没有accessinfo的 情况
            accessInfo = yield wxUtil.getAccessToken(code,os);
        }
        if(typeof accessInfo === 'string')
            accessInfo=JSON.parse(accessInfo);
        let time=(new Date().getTime()-accessInfo.tick)/1000;
        let unionid=accessInfo.unionid;
        let wxopenid="wx_"+accessInfo.openid;
        let openid = wxopenid;
        console.logg("unionid="+unionid)
        if(accessInfo.unionid) {
            yield  redis.setHashItem(redisConst.wxUnionMap,unionid,wxopenid);
            yield  redis.setHashItem(redisConst.wxUnionMap,wxopenid,unionid);
        }
        //判断access_token调用时间是否超时
        if(time >= accessInfo.expires_in){
            accessInfo = yield wxUtil.getAccessToken(code,os);
            if(typeof accessInfo === 'string')
                accessInfo=JSON.parse(accessInfo);
        }
        let access_token = accessInfo.access_token;
        var ret = yield userService.handleWxUserInfo(access_token,accessInfo.openid,ip,stoken,unionid);
        if(ret.code === 500){
            res.send(ret);
            return;
        }
        ret.token=yield tokenService.updateToken(ret.uid);
        ret.stoken=stoken;
        ret.phoneNoCheck=1;
        ret.version=version;
        ret.code=200;
        if(accessInfo.unionid) { ret.weixinUid=accessInfo.unionid; }
        xxCode=yield   userService.makeXxCode(ret.uid)
        ret.xxCode=xxCode;
        if(ret.phoneCode === ret.codeNocheck && ret.phoneCode)  ret.phoneNoCheck=0;
        console.logw('login ret',JSON.stringify(ret));
        res.send(ret);
        return;
    });
    doAsync().catch(function(e) {
        console.logw('error', e.message);
        if(!res.finished)
            res.send({code:500, errmsg:"create user exception ."});
    });
});


function test(){

}


//微信公众号配置服务器的验证
router.get('/weixin/auth',function(req,res){
    console.logw('wexin/auth');
    let query=req.query;
    let signature=query.signature;
    let timestamp=query.timestamp;
    let nonce=query.nonce;
    let echostr=query.echostr;
    //1）将token、timestamp、nonce三个参数进行字典序排序
    //2）将三个参数字符串拼接成一个字符串进行sha1加密
    //3）开发者获得加密后的字符串可与signature对比，标识该请求来源于微信
    let token=cnst.wx_auth_token;
    let secret=cnst.wx_auth_secret;
    let ss=[token,timestamp,nonce];
    ss.sort(function(a,b) {if(a>b) return 1;return -1;});
    let s=ss[0]+ss[1]+ss[2];
    console.logw('info',token,timestamp,nonce,signature,echostr);
    let sres=Token.encodeSha1(s,secret);
    console.logw("sres",sres,signature);
    if(sres===signature) {
        console.logw("验证成功");
        return res.send(echostr);
    }
    console.logw("验证失败");
    res.send('failed');
});

router.get('/weixin/wxapp_login',function(req,res){
    var code = req.query.code;
    console.logg("wxapp_login ",code)
    if(!code)   {

        res.send({code:500,msg:"code is null"})
        return;
    }

    var doAsync= P.coroutine(function*()
    {
        var  appCode=code;
        var os='';
        let  ip= ipUtil.getIp(req,res);
        let  stoken=Token.aesEncodeDef(ip);

        if(code.indexOf("app_")<0)
        {  appCode="app_"+code;
        }

        let  accessInfo=yield wxService.getWxCodeCache(appCode);
        if(!accessInfo)
        {
            var  appid=config.mm_appid;
            var  secret=config.mm_secret;
            accessInfo=yield wxUtil.getAccessTokenFull(appid,secret,code,os);
            if(accessInfo.errcode>0)
            {
                console.logg("ret ",{code:501,msg:"code已过期请重新拉取"})
                res.send({code:501,msg:"code已过期请重新拉取"})
                return;
            }

        }
        if(typeof accessInfo === 'string')
            accessInfo=JSON.parse(accessInfo);
        var  data=accessInfo;
        let time=(new Date().getTime()-accessInfo.tick)/1000;
        var access_token = data.access_token;
        var openid = data.openid;
        var  unionid=data.unionid;
        var   wxopenid="wx_"+openid;
        if(unionid) {
            yield  redis.setHashItem(redisConst.wxUnionMap,unionid,wxopenid);
            yield  redis.setHashItem(redisConst.wxUnionMap,wxopenid,unionid);
        }

        //判断access_token调用时间是否超时
        if(time >= accessInfo.expires_in){
            accessInfo = yield wxUtil.getAccessToken(code,os);
            if(typeof accessInfo === 'string')
                accessInfo=JSON.parse(accessInfo);
        }
        var access_token = accessInfo.access_token;
        var ret = yield userService.handleWxUserInfo(access_token,accessInfo.openid,ip,stoken,unionid);
        if(ret.code === 500){
            res.send(ret);
            return;
        }
        ret.token=yield tokenService.updateToken(ret.uid);
        ret.stoken=stoken;
        ret.phoneNoCheck=1;
        ret.code=200;
        if(accessInfo.unionid) { ret.weixinUid=accessInfo.unionid; }
        xxCode=yield   userService.makeXxCode(ret.uid)
        ret.xxCode=xxCode;
        if(ret.phoneCode === ret.codeNocheck && ret.phoneCode)  ret.phoneNoCheck=0;
        console.logw('login ret',JSON.stringify(ret));
        res.send(ret);

    })

    doAsync().catch(function(e) {
    console.logw('error', e.message);
    if(!res.finished)
        res.send({code:500, errmsg:"wx app create user exception ."});
    })
});

let onTimer = function () {
    //console.logw('test');
    let doAsync = P.coroutine(function* () {
        let len = console.logList.length;
        for (let i = 0; i < len; i++) {
            let s = console.logList.shift();
            if (s) {
                yield fileUtil.writePer15mAsync(s);
            }
        }
    });
    doAsync().catch(function (e) {
        console.logw('wirte File exception', e.message);
    });
};

router.get('/weixin/getOnlineUses',function(req,res){
    var doAsync= P.coroutine(function*()
    {
        var   info=yield  cacheService.getGameUserCount()
        res.send(info);

    })
    doAsync();
})
setInterval(onTimer, 200);
//process.on('uncaughtException', noop)

